package com.ccepc.algmanage.utils;

import com.alibaba.fastjson.JSONObject;
import com.ccepc.demo.api.Hk.HkAuths;
import com.ccepc.demo.api.constants.RecordConstants;
import com.ccepc.demo.api.entity.IdentificationRecord;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hikvision.artemis.sdk.ArtemisHttpUtil;
import com.hikvision.artemis.sdk.config.ArtemisConfig;
import lombok.extern.slf4j.Slf4j;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 海康工具类
 * Author: LuoLing
 */
@Slf4j
public class HkUtils {

    private static final String ARTEMIS_PATH = "/artemis";
    private static ArtemisConfig artemisConfig;

    /**
     * 构造函数
     * @param hkAuths 认证条件
     */
    public HkUtils(HkAuths hkAuths) {
        artemisConfig = new ArtemisConfig(
                hkAuths.getHost(), hkAuths.getAppKey(), hkAuths.getAppSecret()
        );
    }

    public HkUtils(String host, String appKey, String appSecret) {
        artemisConfig = new ArtemisConfig(
                host, appKey, appSecret
        );
    }

    /**
     * 请求方法
     * @param dataApi 接口地址
     * @param requestBody 请求体
     * @return 请求结果
     */
    private String doArtemisRequest(String dataApi, JSONObject requestBody) {
        Map<String, String> path = new HashMap<String, String>(2) {{
            put("https://", dataApi);
        }};
        String body = requestBody.toJSONString();
        String result = null;
        try {
            result = ArtemisHttpUtil.doPostStringArtemis(artemisConfig, path, body, null, null, "application/json");
            log.info("Artemis请求成功:"+result);
        } catch (Exception e) {
            log.error("Artemis请求失败：" + e.getMessage());
        }
        return result;
    }

    /**
     * 按事件类型订阅事件
     * @param eventCode 事件码
     * @return 事件订阅结果
     */
    public String eventSubscriptionByEventTypes(Integer eventCode) {
        String dataApi = ARTEMIS_PATH + "/api/eventService/v1/eventSubscriptionByEventTypes";
        Integer[] eventTypes = {eventCode};
        Integer subType = 2;
        // 订阅事件接收地址
        String eventDest = "http://121.36.109.248:81/algManage/hkEvent/callback";
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("eventTypes", eventTypes);
        jsonObject.put("eventDest", eventDest);
        jsonObject.put("subType", subType);
        return doArtemisRequest(dataApi, jsonObject);
    }

    /**
     * 查询事件订阅信息
     * @return 订阅详情
     */
    public String eventSubscriptionView() {
        String dataApi = ARTEMIS_PATH + "/api/eventService/v1/eventSubscriptionView";
        return doArtemisRequest(dataApi, new JSONObject());
    }

    /**
     * 按事件类型取消订阅
     * @param eventCode 事件码
     * @return 时间取消结果
     */
    public String eventUnSubscriptionByEventTypes(Integer eventCode) {
        Integer[] eventTypes = {eventCode};
        String dataApi = ARTEMIS_PATH + "/api/eventService/v1/eventUnSubscriptionByEventTypes";
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("eventTypes", eventTypes);
        return doArtemisRequest(dataApi, jsonObject);
    }

    /**
     * 获取联动事件列表
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @param pageSize 分页数量
     * @param pageNo 页码
     * @return 联动事件
     */
    public String search(String startTime, String endTime, Integer pageNo, Integer pageSize) {
        String dataApi = ARTEMIS_PATH + "/api/els/v1/events/search";
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("startTime", startTime);
        jsonObject.put("endTime", endTime);
        jsonObject.put("pageSize", pageSize);
        jsonObject.put("pageNo", pageNo);
        return doArtemisRequest(dataApi, jsonObject);
    }

    /**
     * 获取海康视频流
     * @param cameraIndexCode 监控点标识
     * @return 视频地址
     */
    public String getVideoUrls(String cameraIndexCode) {
        String dataApi = ARTEMIS_PATH + "/api/video/v2/cameras/previewURLs";
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("cameraIndexCode", cameraIndexCode);
        return doArtemisRequest(dataApi, jsonObject);
    }

    /**
     * 获取海康历史视频
     * @param cameraIndexCode 监控点标识
     * @param beginTime 视频开始时间
     * @param endTime 视频结束时间
     * @return 历史视频地址
     */
    public String getHistoryVideoUrls(String cameraIndexCode, String beginTime, String endTime) {
        String dataApi = ARTEMIS_PATH + "/api/els/v1/events/search";
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("cameraIndexCode", cameraIndexCode);
        jsonObject.put("beginTime", beginTime);
        jsonObject.put("endTime", endTime);
        return doArtemisRequest(dataApi, jsonObject);
    }

    /**
     * 通过区域id获取下级监控点列表
     * @param regionIndexCode 区域id
     * @param pageSize 单页条数
     * @param pageNo 页数
     * @return 摄像头列表
     */
    public String getCameraList(String regionIndexCode, Integer pageNo, Integer pageSize) {
        String dataApi = ARTEMIS_PATH + "/api/resource/v1/regions/regionIndexCode/cameras";
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("regionIndexCode", regionIndexCode);
        jsonObject.put("pageSize", pageSize);
        jsonObject.put("pageNo", pageNo);
        return doArtemisRequest(dataApi, jsonObject);
    }

    /**
     * 根据摄像头编号获取摄像头详细信息
     * @param cameraIndexCode 摄像头编号
     * @return 摄像头详细信息
     */
    public String getCameraDetails(String cameraIndexCode) {
        String dataApi = ARTEMIS_PATH + "/api/resource/v1/cameras/indexCode";
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("cameraIndexCode", cameraIndexCode);
        return doArtemisRequest(dataApi, jsonObject);
    }


    public String getAllCameraDetails(int pageNo, int pageSize) {
        String dataApi = ARTEMIS_PATH + "/api/resource/v1/cameras";
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("pageNo", pageNo);
        jsonObject.put("pageSize", pageSize);
        return doArtemisRequest(dataApi, jsonObject);
    }

    /**
     * 获取所有监控点列表
     * @param pageNo 页码
     * @param pageSize 单页数量
     * @return 监控点列表
     */
    public String getAllCameraList(Integer pageNo, Integer pageSize) {
        String dataApi = ARTEMIS_PATH + "/api/resource/v1/camera/advance/cameraList";
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("pageNo", pageNo);
        jsonObject.put("pageSize", pageSize);
        return doArtemisRequest(dataApi, jsonObject);
    }

    /**
     * 根据摄像头编码抓图
     * @param cameraIndexCode 摄像头编码
     * @return 截图地址
     */
    public String getPicByCameraIndexCode(String cameraIndexCode) {
        String dataApi = ARTEMIS_PATH + "/api/video/v1/manualCapture";
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("cameraIndexCode", cameraIndexCode);
        return doArtemisRequest(dataApi, jsonObject);
    }

    /**
     * 手动开始录像
     * @param cameraIndexCode 摄像头编号
     * @return 录像开启结果
     */
    public String startCameraRecord(String cameraIndexCode) {
        String dataApi = ARTEMIS_PATH + "/api/video/v1/manualRecord/start";
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("cameraIndexCode", cameraIndexCode);
        // recordType=6表示手动存储，type=1表示设备存储
//        jsonObject.put("recordType", 6);
        jsonObject.put("type", 1);
        return doArtemisRequest(dataApi, jsonObject);
    }

    /**
     * 手动停止录像
     * @param cameraIndexCode 摄像头编号
     * @return 录像开启结果
     */
    public String stopCameraRecord(String cameraIndexCode, String taskID) {
        String dataApi = ARTEMIS_PATH + "/api/video/v1/manualRecord/stop";
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("cameraIndexCode", cameraIndexCode);
        jsonObject.put("taskID", taskID);
        jsonObject.put("type", 0);
        return doArtemisRequest(dataApi, jsonObject);
    }

    /**
     * 解析接收的订阅消息返回结果
     * @param request 订阅消息
     * @return 所需结果
     */
    public static IdentificationRecord parseSubscriptionInfo(String request) {
        ObjectMapper objectMapper = new ObjectMapper();
        DateTimeFormatter formatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
        IdentificationRecord identificationRecord = new IdentificationRecord();
        try {
            // 读取属性
            JsonNode jsonNode = objectMapper.readTree(request);
            JsonNode events = jsonNode
                    .path("params")
                    .path("events")
                    .path(0);
            JsonNode eventDetails = events.path("eventDetails").path(0);
            JsonNode linkageResultNode = events
                    .path("linkageResult")
                    .path(0);

            String content = linkageResultNode.path("content").asText();
            JsonNode contentNode = objectMapper.readTree(content).path(0);
            String picUrls = contentNode.path("picUrls").path(0).asText();
            // 属性赋值
            if (!picUrls.isEmpty()) {
                identificationRecord.setIdenResults(RecordConstants.HK_URL_PRE + picUrls);
            }
            identificationRecord.setDeviceNo(eventDetails.path("srcIndex").asText());
            identificationRecord.setEventName(eventDetails.path("srcName").asText());
            identificationRecord.setCreatedTime(LocalDateTime.parse(events.path("happenTime").asText(), formatter));
            identificationRecord.setEventLvl(Integer.parseInt(events.path("eventLvl").asText()));
            identificationRecord.setIsPush(0);
            identificationRecord.setIsHandle(0);
            identificationRecord.setEventCode(eventDetails.path("eventType").asText());
            return identificationRecord;
        } catch (JsonProcessingException e) {
            log.error(e.getMessage());
            return null;
        }
    }

}
